<?php
/**
 * File contains MongodbSession handler class
 *
 * @author Pritesh Loke <priteshloke@gmail.com>
 * @version 1.0
 */

/**
 * This is the MongoDb session handler class
 *
 * @package px
 * @category API
 */
class MongodbSession
{
	const MONGO_USERNAME = NULL;
	const MONGO_PASSWORD = NULL;
	const MONGO_HOST = Mongo::DEFAULT_HOST;
	const MONGO_PORT = Mongo::DEFAULT_PORT;
	const MONGO_DATABASE = 'core_data';
	const MONGO_COLLECTION = 'sessions';
	const MONGO_EXPIRY = 3600;
	private $__mongo_collection = NULL;
	private $__current_session = NULL;
	/**
	 *
	 * Default constructor set default parameter
	 * @access public
	 */
	public function __construct()
	{
		$this->__connect();
		session_set_save_handler(
		array(&$this, 'open'),
		array(&$this, 'close'),
		array(&$this, 'read'),
		array(&$this, 'write'),
		array(&$this, 'destroy'),
		array(&$this, 'gc')
		);
	}
	/**
	 *
	 * connectes the mongo database and create collection
	 * @access private
	 */
	private function __connect()
	{
		$connection_string = sprintf('mongodb://%s:%s', self::MONGO_HOST, self::MONGO_PORT);
		if (self::MONGO_USERNAME != null && self::MONGO_PASSWORD != null)
		{
			$connection_string = "mongodb://{SELF::MONGO_USERNAME}:{SELF::MONGO_PASSWORD}@{SELF::MONGO_HOST}:{SELF::MONGO_PORT}";
			$connection_string = sprintf('mongodb://%s:%s@%s:%s', self::MONGO_USERNAME, self::MONGO_PASSWORD, self::MONGO_USERNAME, self::MONGO_PASSWORD);
		}
		$object_mongo = new Mongo($connection_string);
		$object_mongo = $object_mongo->{self::MONGO_DATABASE};
		$this->__mongo_collection = $object_mongo->{self::MONGO_COLLECTION};
	}
	/**
	 * 
	 * check for collection object
	 * @access public
	 * @param string $session_path
	 * @param string $session_name
	 * @return boolean
	 */
	public function open($session_path, $session_name)
	{
		$result = false;
		if ($this->__mongo_collection != NULL)
		{
			$result = false;
		}
		return $result;
	}
	/**
	 * 
	 * doing noting
	 * @access public
	 * @return boolean
	 */
	public function close()
	{
		return true;
	}
	/**
	 * 
	 * Reading session data based on id
	 * @access public
	 * @param string $session_id
	 * @return mixed 
	 */
	public function read($session_id)
	{
		print "Read <br />";
		$result = NULL;
		$expiry = time();
		$query['_id'] = $session_id;
		$query['expiry'] = array('$gte' => $expiry);
		print_r($query);
		$result = $this->__mongo_collection->findone($query);
		if ($result)
		{
			$this->__current_session = $result;
		}
		return $result['data'];
	}
	/**
	 * 
	 * Writing session data
	 * @access public
	 * @param string $session_id
	 * @param mixed $data
	 * @return boolean
	 */
	public function write($session_id, $data)
	{
		$result = true;
		$expiry = $this->__getExpriry();
		$session_data = array();
		if (empty($this->__current_session))
		{
			$session_id = $session_id;
			$session_data['_id'] = $session_id;
			$session_data['data'] = $data;
			$session_data['expiry'] = $expiry;
		}
		else
		{
			$session_data = (array) $this->__current_session;
			$session_data['data'] = $data;
			$session_data['expiry'] = $expiry;
				
		}
		$query['_id'] = $session_id;
		$record = $this->__mongo_collection->findOne($query);
		if ($record == null)
		{
			$this->__mongo_collection->insert($session_data);
		}
		else
		{
			$record['data'] = $data;
			$record['expiry'] = $expiry;
			$this->__mongo_collection->save($record);
		}
		return true;
	}
	/**
	 * 
	 * remove session data
	 * @access public
	 * @param string $session_id
	 * @return boolean
	 */
	public function destroy($session_id)
	{
		$query['_id'] = $session_id;
		$this->__mongo_collection->remove($query, true);
		return true;
	}
	/**
	 * 
	 * Garbage collection
	 * @access public
	 * @return boolean
	 */
	public function gc()
	{
		$query = array();
		$query['expiry'] = array(':lt' => time());
		$this->__mongo_collection->remove($query, array('justOne' => false));
		return true;

	}
	/**
	 * 
	 * get expiry
	 * @access private
	 * @return int
	 */
	private function __getExpriry()
	{
		return time() + self::MONGO_EXPIRY;
	}
}